home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / utility / 252 / dskpcsrc / expressi.mod < prev    next >
Text File  |  1988-02-13  |  11KB  |  350 lines

  1. IMPLEMENTATION MODULE Expression;
  2.  
  3.  
  4.    (*$S-,$T- turn off stack and range checking *) 
  5.  
  6.    IMPORT GEMAESbase;
  7.    IMPORT GEMDOS;
  8.    IMPORT M2Conversions;
  9.    IMPORT Text;
  10.    IMPORT Screen;
  11.    IMPORT Resource;
  12.    IMPORT Icon;
  13.    IMPORT Readout;
  14.    IMPORT Float;
  15.  
  16.  
  17.    CONST
  18.       StackSize = 30;
  19.       None      = 0;
  20.       Bell      = 07C;
  21.  
  22.    TYPE OperatorElement = RECORD
  23.       Operand      : Float.DataElement;
  24.       ValidOperand : BOOLEAN;
  25.       MathRoutine  : Float.MathRoutineProc;
  26.       Precedence   : CARDINAL;
  27.    END;
  28.  
  29.    VAR
  30.       UpdateRegion  : Screen.Box;
  31.       Stack         : ARRAY [0..StackSize] OF OperatorElement;
  32.       TOS           : CARDINAL;   (* Top Of Stack *)
  33.       Memory        : ARRAY [0..9] OF Float.DataElement;
  34.       NumberBase    : INTEGER;
  35.       SpecialKey    : INTEGER;
  36.       ProgramMode   : BOOLEAN;
  37.  
  38.    (*----------------------- LOCAL ROUTINE ----------------------------*)
  39.  
  40.    PROCEDURE ClearStack;
  41.  
  42.    BEGIN
  43.       Stack[0].Precedence := 0;
  44.       Float.MakeSmallLiteral ( 0, Stack[0].Operand );
  45.       Stack[0].ValidOperand := TRUE;
  46.       TOS := 0;
  47.    END ClearStack;
  48.  
  49.    (*----------------------- LOCAL ROUTINE ----------------------------*)
  50.  
  51.    PROCEDURE Error;
  52.  
  53.    BEGIN
  54.       Float.Error := TRUE;
  55.       Readout.Write ( "Error ", UpdateRegion );
  56.    END Error;
  57.  
  58.    (*----------------------- LOCAL ROUTINE ----------------------------*)
  59.  
  60.    PROCEDURE DisplayTOS;
  61.  
  62.    VAR
  63.       Success : BOOLEAN;
  64.       Buffer  : Text.String80;
  65.  
  66.    BEGIN
  67.       IF NOT Float.Error THEN
  68.          Buffer[0] := CHR (0);
  69.          Float.Image ( Stack[TOS].Operand, Buffer );
  70.          Success := Text.ConcatChar ( Buffer, ' ', Buffer );
  71.          Readout.Write ( Buffer, UpdateRegion );
  72.       END;
  73.    END DisplayTOS;
  74.  
  75.    (*----------------------- LOCAL ROUTINE ----------------------------*)
  76.  
  77.    PROCEDURE SetBase ( Base : INTEGER );
  78.  
  79.    VAR Success : BOOLEAN;
  80.  
  81.    BEGIN
  82.       Reduce ( FALSE );
  83.       IF Base = Resource.D9HEX THEN
  84.          Success := Float.SetBase ( 16, Stack[TOS].Operand );
  85.       ELSIF Base = Resource.D9DEC THEN
  86.          Success := Float.SetBase ( 10, Stack[TOS].Operand );
  87.       ELSIF Base = Resource.D9OCT THEN
  88.          Success := Float.SetBase ( 8, Stack[TOS].Operand );
  89.       ELSIF Base = Resource.D9BIN THEN
  90.          Success := Float.SetBase ( 2, Stack[TOS].Operand );
  91.       END;
  92.       IF NOT Success THEN
  93.          Error;
  94.       END;
  95.       NumberBase := Base;
  96.    END SetBase;
  97.  
  98.    (*----------------------- LOCAL ROUTINE ----------------------------*)
  99.  
  100.    PROCEDURE Reduce ( StopAtParenthesis : BOOLEAN );
  101.  
  102.    BEGIN
  103.       LOOP
  104.          IF TOS = 0 THEN
  105.             EXIT;
  106.          ELSIF Stack[TOS].Precedence = 0 THEN
  107.             Stack[TOS-1].Operand    := Stack[TOS].Operand;
  108.             Stack[TOS].ValidOperand := FALSE;
  109.             DEC (TOS);
  110.             Stack[TOS].ValidOperand := TRUE;
  111.             IF StopAtParenthesis THEN
  112.                EXIT;
  113.             END;
  114.          ELSE
  115.             IF Stack[TOS].ValidOperand AND Stack[TOS-1].ValidOperand THEN
  116.                Stack[TOS].MathRoutine (
  117.                   Stack[TOS-1].Operand,
  118.                   Stack[TOS].Operand,
  119.                   Stack[TOS-1].Operand );
  120.                Stack[TOS].ValidOperand := FALSE;
  121.                DEC (TOS);
  122.                Stack[TOS].ValidOperand := TRUE;
  123.                IF Float.Error THEN
  124.                   Error;
  125.                   EXIT;
  126.                END;
  127.             ELSE
  128.                Error;
  129.                EXIT;
  130.             END;
  131.          END;
  132.       END (* LOOP *);
  133.    END Reduce;
  134.  
  135.    (*----------------------- LOCAL ROUTINE ----------------------------*)
  136.  
  137.    PROCEDURE ImmediateKey ( Key : INTEGER ) : BOOLEAN;
  138.  
  139.    VAR KeyProcessed : BOOLEAN;
  140.  
  141.    BEGIN
  142.       KeyProcessed := TRUE;
  143.       IF (Key = Resource.D9STO) OR
  144.          (Key = Resource.D9RCL) OR
  145.          (Key = Resource.D9SUM) THEN
  146.             SpecialKey := Key;
  147.       ELSE
  148.          IF (Key = Resource.D9HEX) OR
  149.             (Key = Resource.D9DEC) OR
  150.             (Key = Resource.D9OCT) OR
  151.             (Key = Resource.D9BIN) THEN
  152.                SetBase ( Key );
  153.          ELSIF Key = Resource.D9PLSMIN THEN
  154.             Float.ChangeSign ( Stack[TOS].Operand, Stack[TOS].Operand );
  155.          ELSIF Key = Resource.D9CE THEN
  156.             ClearStack;
  157.          ELSIF Key = Resource.D9SIN THEN
  158.             Float.Sin ( Stack[TOS].Operand, Stack[TOS].Operand );
  159.          ELSIF Key = Resource.D9COS THEN
  160.             Float.Cos ( Stack[TOS].Operand, Stack[TOS].Operand );
  161.          ELSIF Key = Resource.D9TAN THEN
  162.             Float.Tan ( Stack[TOS].Operand, Stack[TOS].Operand );
  163.          ELSIF Key = Resource.D9ASIN THEN
  164.             Float.ASin ( Stack[TOS].Operand, Stack[TOS].Operand );
  165.          ELSIF Key = Resource.D9ACOS THEN
  166.             Float.ACos ( Stack[TOS].Operand, Stack[TOS].Operand );
  167.          ELSIF Key = Resource.D9ATAN THEN
  168.             Float.ATan ( Stack[TOS].Operand, Stack[TOS].Operand );
  169.          ELSIF Key = Resource.D9RECIP THEN
  170.             Float.Reciprocal ( Stack[TOS].Operand, Stack[TOS].Operand );
  171.          ELSIF Key = Resource.D9SQRT THEN
  172.             Float.SquareRoot ( Stack[TOS].Operand, Stack[TOS].Operand );
  173.          ELSIF Key = Resource.D9LOG THEN
  174.             Float.Log ( Stack[TOS].Operand, Stack[TOS].Operand );
  175.          ELSIF Key = Resource.D9LN THEN
  176.             Float.Ln ( Stack[TOS].Operand, Stack[TOS].Operand );
  177.          ELSIF Key = Resource.D91SC THEN 
  178.             Float.OnesComplement ( Stack[TOS].Operand, Stack[TOS].Operand );
  179.          ELSIF Key = Resource.D9PGM THEN
  180.             IF ProgramMode THEN
  181.                ProgramMode := FALSE;
  182.             ELSE
  183.                ProgramMode  := TRUE;
  184.                KeyProcessed := FALSE;
  185.             END;
  186.          ELSE
  187.             KeyProcessed := FALSE;
  188.          END;
  189.          IF Float.Error THEN
  190.             Error;
  191.          ELSIF KeyProcessed THEN
  192.             DisplayTOS;
  193.          END;
  194.       END;
  195.       RETURN (KeyProcessed);
  196.    END ImmediateKey;
  197.  
  198.    (*----------------------- LOCAL ROUTINE ----------------------------*)
  199.  
  200.    PROCEDURE PushReduce (
  201.       OperatorRoutine    : Float.MathRoutineProc;
  202.       OperatorPrecedence : CARDINAL;
  203.       StackPrecedence    : CARDINAL );
  204.  
  205.    BEGIN
  206.       LOOP
  207.          IF OperatorPrecedence > Stack[TOS].Precedence THEN
  208.             INC (TOS);
  209.             IF TOS > StackSize THEN
  210.                Error;
  211.             ELSE
  212.                Stack[TOS].MathRoutine := OperatorRoutine;
  213.                Stack[TOS].Precedence  := StackPrecedence;
  214.             END;
  215.             EXIT;
  216.          ELSE
  217.             IF Stack[TOS].ValidOperand AND Stack[TOS-1].ValidOperand THEN
  218.                Stack[TOS].MathRoutine (
  219.                   Stack[TOS-1].Operand,
  220.                   Stack[TOS].Operand,
  221.                   Stack[TOS-1].Operand );
  222.                Stack[TOS].ValidOperand := FALSE;
  223.                DEC (TOS);
  224.                Stack[TOS].ValidOperand := TRUE;
  225.                DisplayTOS;
  226.             ELSE
  227.                Error;
  228.                EXIT;
  229.             END;
  230.          END;
  231.       END (* LOOP *);
  232.    END PushReduce;
  233.  
  234.    (*----------------------- LOCAL ROUTINE ----------------------------*)
  235.  
  236.    PROCEDURE Evaluate (
  237.       Key           : INTEGER;
  238.       NumberEntered : BOOLEAN );
  239.  
  240.    BEGIN
  241.       IF Key = Resource.D9DIV THEN
  242.          PushReduce ( Float.Divide, 9, 10 );
  243.       ELSIF Key = Resource.D9MULT THEN
  244.          PushReduce ( Float.Multiply, 9, 10 );
  245.       ELSIF Key = Resource.D9MINUS THEN
  246.          PushReduce ( Float.Subtract, 7, 8 );
  247.       ELSIF Key = Resource.D9PLUS THEN
  248.          PushReduce ( Float.Add, 7, 8 );
  249.       ELSIF Key = Resource.D9YTOX THEN
  250.          PushReduce ( Float.Power, 12, 11 );
  251.       ELSIF Key = Resource.D9SHF THEN
  252.          PushReduce ( Float.Shift, 5, 6 );
  253.       ELSIF Key = Resource.D9AND THEN
  254.          PushReduce ( Float.And, 3, 4 );
  255.       ELSIF Key = Resource.D9OR THEN
  256.          PushReduce ( Float.Or, 1, 2 );
  257.       ELSIF Key = Resource.D9XOR THEN
  258.          PushReduce ( Float.ExclusiveOr, 5, 6 );
  259.       ELSIF Key = Resource.D9LPAREN THEN
  260.          INC (TOS);
  261.          IF TOS > StackSize THEN
  262.             Error;
  263.          ELSE
  264.             Float.MakeSmallLiteral ( 0, Stack[TOS].Operand );
  265.             Stack[TOS].ValidOperand := TRUE;
  266.             Stack[TOS].Precedence   := 0;
  267.          END;
  268.       ELSIF (Key = Resource.D9RPAREN) OR
  269.             (Key = Resource.D9EQUALS) THEN
  270.          Reduce ( Key = Resource.D9RPAREN );
  271.          DisplayTOS;
  272.       END;
  273.    END Evaluate;
  274.  
  275.    (*------------------------------------------------------------------*)
  276.  
  277.    PROCEDURE CompareTOS ( VAR Status : (* OUT *) CompareResult );
  278.  
  279.    BEGIN
  280.       Status := CompareResult (Float.Compare ( Stack[TOS].Operand ));
  281.    END CompareTOS;
  282.  
  283.    (*------------------------------------------------------------------*)
  284.  
  285.    PROCEDURE ProcessKey (
  286.       Key           : INTEGER;
  287.       WindowBorders : Screen.Box;
  288.       VAR Number    : ARRAY OF CHAR );
  289.  
  290.    VAR
  291.       Register         : CARDINAL;
  292.       NumberWasEntered : BOOLEAN;
  293.       Success          : BOOLEAN;
  294.  
  295.    BEGIN
  296.       UpdateRegion     := WindowBorders;
  297.       NumberWasEntered := (Text.Length ( Number ) <> 0);
  298.       IF Float.Error THEN
  299.          ClearStack;
  300.          Float.Error := FALSE;
  301.       END;
  302.       IF SpecialKey = None THEN
  303.          IF NumberWasEntered THEN
  304.             IF Float.Value ( Number, Stack[TOS].Operand ) THEN
  305.                Stack[TOS].ValidOperand := TRUE;
  306.             ELSE
  307.                Error;
  308.             END;
  309.          END;
  310.          IF NOT Float.Error THEN
  311.             IF NOT ImmediateKey ( Key ) THEN
  312.                Evaluate ( Key, NumberWasEntered );
  313.             END;
  314.          END;
  315.  
  316.       ELSE
  317.          M2Conversions.ConvertToCardinal ( Number, Success, Register );
  318.          IF SpecialKey = Resource.D9STO THEN
  319.             Memory[Register] := Stack[TOS].Operand;
  320.  
  321.          ELSIF SpecialKey = Resource.D9SUM THEN
  322.             Float.Add ( Stack[TOS].Operand, Memory[Register], Memory[Register] );
  323.  
  324.          ELSIF SpecialKey = Resource.D9RCL THEN
  325.             Stack[TOS].Operand      := Memory[Register];
  326.             Stack[TOS].ValidOperand := TRUE;
  327.             DisplayTOS;
  328.  
  329.          END;
  330.          SpecialKey := None;
  331.       END;
  332.    END ProcessKey;
  333.  
  334.  
  335. VAR
  336.    Index   : CARDINAL;
  337.    Success : BOOLEAN;
  338.  
  339. BEGIN
  340.    ClearStack;
  341.    ProgramMode := FALSE;
  342.    NumberBase  := Resource.D9DEC;
  343.    SpecialKey  := None;
  344.    Success     := Float.SetBase ( 10, Stack[TOS].Operand );
  345.    FOR Index := 0 TO 9 DO
  346.       Float.MakeSmallLiteral ( 0, Memory[Index] );
  347.    END;
  348. END Expression.
  349.  
  350.